package com.andy.android.serialporttest;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.telephony.CarrierConfigManager.Gps;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.DatePicker;
import android.widget.TimePicker;

import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;

import java.io.File;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class Util {
    /**
     * 字节数组转换为十六进制字符串
     *
     * @param b
     *            byte[] 需要转换的字节数组
     * @return String 十六进制字符串
     */
    public static final String byte2hex(byte b[]) {
        if (b == null) {
            throw new IllegalArgumentException("Argument b ( byte array ) is null! ");
        }

        String hs = "";
        String stmp = "";

        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xff);
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    /**
     * 十六进制串转化为byte数组
     *
     * @return the array of byte
     */
    public static byte[] hex2byte(String hex) throws IllegalArgumentException {
        if (hex.length() % 2 != 0) {
            throw new IllegalArgumentException();
        }

        char[] arr = hex.toCharArray();
        byte[] b = new byte[hex.length() / 2];

        for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) {
            String swap = "" + arr[i++] + arr[i];
            int byteint = Integer.parseInt(swap, 16) & 0xFF;
            b[j] = new Integer(byteint).byteValue();
        }

        return b;
    }

    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * ASCII码字符串转数字字符串
     * @param
     * @return 字符串
     */

    public static String AsciiStringToString(String content) {
        String result = "";
        int length = content.length() / 2;
        for (int i = 0; i < length; i++) {
            String c = content.substring(i * 2, i * 2 + 2);
            int a = hexStringToAlgorism(c);
            char b = (char) a;
            String d = String.valueOf(b);
            result += d;
        }
        return result;
    }

    /**
     * 十六进制字符串装十进制
     *
     * @param hex
     *            十六进制字符串
     * @return 十进制数值
     */
    public static int hexStringToAlgorism(String hex) {
        hex = hex.toUpperCase();
        int max = hex.length();

        int result = 0;

        for (int i = max; i > 0; i--) {
            char c = hex.charAt(i - 1);
            int algorism = 0;
            if (c >= '0' && c <= '9') {
                algorism = c - '0';
            } else {
                algorism = c - 55;
            }
            result += Math.pow(16, max - i) * algorism;
        }
        return result;
    }

    /**
     * 将十进制转换为指定长度的十六进制字符串
     *
     * @param algorism
     *           int 十进制数字
     * @param maxLength
     *            int 转换后的十六进制字符串长度
     * @return String 转换后的十六进制字符串
     */
    public static String algorismToHEXString(int algorism, int maxLength) {
        String result = "";
        result = Integer.toHexString(algorism);

        if (result.length() % 2 == 1) {
            result = "0" + result;
        }
        return patchHexString(result.toUpperCase(), maxLength);
    }

    /**
     * HEX字符串前补0，主要用于长度位数不足。
     *
     * @param str
     *            String 需要补充长度的十六进制字符串
     * @param maxLength
     *            int 补充后十六进制字符串的长度
     * @return 补充结果
     */
    static public String patchHexString(String str, int maxLength) {
        String temp = "";
        for (int i = 0; i < maxLength - str.length(); i++) {
            temp = "0" + temp;
        }

        str = (temp + str).substring(0, maxLength);

        return str;
    }

    /**
     * 字节数组转为普通字符串（ASCII对应的字符）
     *
     * @param bytearray
     *            byte[]
     * @return String
     */
    public static String bytetoString(byte[] bytearray) {
        String result = "";
        char temp;

        int length = bytearray.length;

        for (int i = 0; i < length; i++) {
            temp = (char) bytearray[i];
            result += temp;
        }
        return result;
    }

    /**
     * 字符串转换成十六进制字符串
     * @param str 待转换的ASCII字符串
     * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
     */
    public static String str2HexStr(String str)
    {

        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;

        for (int i = 0; i < bs.length; i++)
        {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            sb.append(' ');
        }
        return sb.toString().trim();
    }

    public static int hexCharToInt(char c) {
        if ((c >= '0') && (c <= '9'))
            return (c - '0');
        if ((c >= 'A') && (c <= 'F'))
            return (c - 'A' + 10);
        if ((c >= 'a') && (c <= 'f'))
            return (c - 'a' + 10);

        throw new RuntimeException("invalid hex char '" + c + "'");
    }

    /**

     * 将字符串转成ASCII值
     */
    public static String strToASCII(String data) {
        String requestStr = "";
        for (int i = 0; i < data.length(); i++) {
            char a = data.charAt(i);
            int aInt = (int) a;
            requestStr = requestStr + integerToHexString(aInt);
        }
        return requestStr;
    }

    /**
     * 将十进制整数转为十六进制数，并补位
     * */
    public static String integerToHexString(int s) {
        String ss = Integer.toHexString(s);
        if (ss.length() % 2 != 0) {
            ss = "0" + ss;//0F格式
        }
        return ss.toUpperCase();
    }

    public static String convertHexToString(String hex){

        StringBuilder sb = new StringBuilder();
        StringBuilder temp = new StringBuilder();

        //49204c6f7665204a617661 split into two characters 49, 20, 4c...
        for( int i=0; i<hex.length()-1; i+=2 ){
            //grab the hex in pairs
            String output = hex.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            //convert the decimal to character
            sb.append((char)decimal);
            temp.append(decimal);
        }
        return sb.toString();
    }

    //往字符串数组追加新数据
    public static String[] insert(String[] arr, String str) {
        int size = arr.length;  //获取数组长度
        String[] tmp = new String[size + 1];  //新建临时字符串数组，在原来基础上长度加一
        for (int i = 0; i < size; i++){  //先遍历将原来的字符串数组数据添加到临时字符串数组
            tmp[i] = arr[i];
        }
        tmp[size] = str;  //在最后添加上需要追加的数据
        return tmp;  //返回拼接完成的字符串数组
    }

    public static double baoliu2(double f){
        double temp = f;
        BigDecimal b = new BigDecimal(temp);
        //保留3位小数
        double res = b.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        return  res;
    }

    public static byte[] rtcm_to_h10b(int len , byte[] rtcm){
        byte[] buf_rtcm_len = new byte[2];
        String rtcm_len_buf = String.format("%02X", len);
        rtcm_len_buf = Util.patchHexString(rtcm_len_buf,4);
        //16进制转BYTE[]
        buf_rtcm_len = Util.hex2byte(rtcm_len_buf);
        int len_RTCM_Buf = buf_rtcm_len.length;

        //组发送数据包
        byte[] datatemp = new byte[7];
        datatemp[0] = (byte)0x3A;
        datatemp[1] = (byte)0x3A;
        datatemp[2] = (byte)0x3A;
        datatemp[3] = (byte)0x3A;
        datatemp[4] = (byte)0x3A;
        datatemp[5] = buf_rtcm_len[0];
        datatemp[6] = buf_rtcm_len[1];

        byte[] temp = Util.hex2byte(Util.byte2hex(rtcm));

        byte[] data = new byte[7+len];

        data = concat(datatemp, temp);
        return data;
    }

    public static <T> byte[] concat(byte[] first, byte[] second) {
        byte[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

    public static String asciiToString(String value)
    {
        StringBuffer sbu = new StringBuffer();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    /** * 提供精确的乘法运算。
     *  @param v1 被乘数
     *  @param v2 乘数
     *  @return 两个参数的积
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /** * 提供精确的加法运算。
     *  @param v1 被加数
     *  @param v2 加数
     *  @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    /** * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
     *  定精度，以后的数字四舍五入。
     *  @param v1    被除数
     *  @param v2    除数
     *  @param scale 表示表示需要精确到小数点以后几位。
     *  @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static Double LatAnalysis(String Lat, String NS){
        //String tmp = String.valueOf(Lat);
        int LatZS = Integer.parseInt(Lat.substring(0,2));
        Double LatXS = div(Double.parseDouble(Lat.substring(2)), 60, 10);
        Double Lattemp1 = Util.add(LatZS, LatXS);
        if(NS == "N"){
            int n_mode = 1;
            Lattemp1 = mul(Lattemp1, n_mode);
        }
        if(NS == "S"){
            int s_mode = -1;
            Lattemp1 = mul(Lattemp1, s_mode);
        }
        return Lattemp1;
    }

    public static Double LngAnalysis(String Lng, String EW){
        //String tmp = String.valueOf(Lng);
        int LngZS = Integer.parseInt(Lng.substring(0,3));
        Double LngXS = div(Double.parseDouble(Lng.substring(3)), 60, 10);
        Double Lattemp2 = add(LngZS, LngXS);
        if(EW == "E"){
            int e_mode = 1;
            Lattemp2 = mul(Lattemp2, e_mode);
        }
        if(EW== "W"){
            int w_mode = -1;
            Lattemp2 = mul(Lattemp2, w_mode);
        }
        return Lattemp2;
    }

    public static int LatAnalysis_Du(Double Lat){
        String tmp = String.valueOf(Lat.toString());
        int Lat_Du = Integer.parseInt(tmp.substring(0,2));
        return Lat_Du;
    }

    public static int LatAnalysis_Fen(Double Lat){
        String tmp = String.valueOf(Lat);
        return Integer.parseInt(tmp.substring(2,4));
    }

    public static int LatAnalysis_Miao(Double Lat){
        String temp = String.valueOf(Lat);
        int tmp = Integer.parseInt(temp.substring(5));
        tmp = tmp * 60;
        return tmp/1000;
    }

    public static int LatAnalysis_Miao_low(Double Lat){
        String temp = String.valueOf(Lat);
        int tmp = Integer.parseInt(temp.substring(5));
        tmp = tmp * 60;
        return tmp % 1000;
    }

    public static int LngAnalysis_Du(Double Lng){
        String tmp = String.valueOf(Lng);
        return Integer.parseInt(tmp.substring(0,3));
    }

    public static int LngAnalysis_Fen(Double Lng){
        String tmp = String.valueOf(Lng);
        return Integer.parseInt(tmp.substring(3,5));
    }

    public static int LngAnalysis_Miao(Double Lng){
        String temp = String.valueOf(Lng);
        int tmp = Integer.parseInt(temp.substring(6));
        tmp = tmp * 60;
        return tmp/1000;
    }

    public static int LngAnalysis_Miao_low(Double Lng){
        String temp = String.valueOf(Lng);
        int tmp = Integer.parseInt(temp.substring(5));
        tmp = tmp * 60;
        return tmp % 1000;
    }

    public static double rmc_speed(double speed){
        double rmc_speed = 0.0;
        //1852米/小时= 0.5144 米/秒
        double speed_temp = mul(speed, 0.5144);
        //米/秒
        rmc_speed = baoliu2(speed_temp);
        return rmc_speed;
    }

    public static String convertStringToHex(String str){

        char[] chars = str.toCharArray();

        StringBuffer hex = new StringBuffer();
        for(int i = 0; i < chars.length; i++){
            hex.append(Integer.toHexString((int)chars[i]));
        }

        return hex.toString();
    }

    private static int CountStr(String str1, String str2){
        int index = 0;
        int count = 0;
        while ((index = str1.indexOf(str2,index))!= -1){
            index = index + str2.length();
            count++;
        }
        return count;
    }


    /**
     * 获取当前时间
     *  格式：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getTime() {
        Date date = new Date();// 创建一个时间对象，获取到当前的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置时间显示格式
        return sdf.format(date);
    }

    /**
     * 获取当前时间
     *  格式：HH:mm
     * @return
     */
    public static String getTimeMin() {
        Date date = new Date();// 创建一个时间对象，获取到当前的时间
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");// 设置时间显示格式
        return sdf.format(date);
    }

    /**
     * 获取当前日期
     *  格式：yyyy-MM-dd
     * @return
     */
    public static String getDate() {
        Date date = new Date();// 创建一个时间对象，获取到当前的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 设置日期显示格式
        return sdf.format(date);
    }

    /**
     * 获取当前日期
     *  格式：MM-dd
     * @return
     */
    public static String getDateMonth() {
        Date date = new Date();// 创建一个时间对象，获取到当前的时间
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");// 设置日期显示格式
        return sdf.format(date);
    }

    /**
     * 获取当前日期
     *  格式：yyyy-MM-dd HH:mm
     * @return
     */
    public static String getDateTimeMin() {
        Date date = new Date();// 创建一个时间对象，获取到当前的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");// 设置日期显示格式
        return sdf.format(date);
    }

    /**
     * 保留num小数并转换成string类型
     * @param dou
     * @return
     */
    public static String coverFormat(String num, double dou){
        DecimalFormat dfs= new DecimalFormat(num);
        return dfs.format(dou);
    }

    /**
     * 保留8小数
     * @param
     * @return
     */
    public static double keep8Decimal(double d){
        BigDecimal bd=new BigDecimal(d);
        double d1=bd.setScale(8,BigDecimal.ROUND_HALF_UP).doubleValue();
        return d1;
    }

    public static boolean isMobileNO(String mobileNums) {
        /**
         * 判断字符串是否符合手机号码格式
         * 移动号段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,184,187,188
         * 联通号段: 130,131,132,145,155,156,170,171,175,176,185,186
         * 电信号段: 133,149,153,170,173,177,180,181,189
         * @param str
         * @return 待检测的字符串
         */
        String telRegex = "^((13[0-9])|(14[5,7,9])|(15[^4])|(18[0-9])|(17[0,1,3,5,6,7,8]))\\d{8}$";// "[1]"代表第1位为数字1，"[358]"代表第二位可以为3、5、8中的一个，"\\d{9}"代表后面是可以是0～9的数字，有9位。
        if (TextUtils.isEmpty(mobileNums)) {
            return false;
        } else {
            return mobileNums.matches(telRegex);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void openTorch(Context context) {
        try {
            CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            cameraManager.setTorchMode("0", false);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void closeTorch(Context context) {
        try {
            CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
            cameraManager.setTorchMode("0", true);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    // 状态栏高度
    private static  int statusBarHeight = 0;
    // 屏幕像素点
    private static final Point screenSize = new Point();

    // 获取屏幕像素点
    public static Point getScreenSize(Activity context) {

        if (context == null) {
            return screenSize;
        }
        WindowManager wm = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        if (wm != null) {
            DisplayMetrics mDisplayMetrics = new DisplayMetrics();
            Display diplay = wm.getDefaultDisplay();
            if (diplay != null) {
                diplay.getMetrics(mDisplayMetrics);
                int W = mDisplayMetrics.widthPixels;
                int H = mDisplayMetrics.heightPixels;
                if (W * H > 0 && (W > screenSize.x || H > screenSize.y)) {
                    screenSize.set(W, H);
                }
            }
        }
        return screenSize;
    }

    // 获取状态栏高度
    public static int getStatusBarHeight(Context context) {
        if (statusBarHeight <= 0) {
            Rect frame = new Rect();
            ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            statusBarHeight = frame.top;
        }
        if (statusBarHeight <= 0) {
            try {
                Class<?> c = Class.forName("com.android.internal.R$dimen");
                Object obj = c.newInstance();
                Field field = c.getField("status_bar_height");
                int x = Integer.parseInt(field.get(obj).toString());
                statusBarHeight = context.getResources().getDimensionPixelSize(x);

            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        return statusBarHeight;
    }

    /**
     * 判断手机位置信息开关是否打开
     * @param context
     * @return
     */
    public static boolean isLocationEnabled(Context context) {
        int locationMode = 0;
        String locationProviders;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);

            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
                return false;
            }
            return locationMode != Settings.Secure.LOCATION_MODE_OFF;
        }else{
            locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            return !TextUtils.isEmpty(locationProviders);
        }
    }

    //DatePicker隐藏年
    public static void hideYear(DatePicker mDatePicker) {
        try {
            /* 处理android5.0以上的特殊情况 */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                int daySpinnerId = Resources.getSystem().getIdentifier("year", "id", "android");
                if (daySpinnerId != 0) {
                    View daySpinner = mDatePicker.findViewById(daySpinnerId);
                    if (daySpinner != null) {
                        daySpinner.setVisibility(View.GONE);
                    }
                }
            } else {
                Field[] datePickerfFields = mDatePicker.getClass().getDeclaredFields();
                for (Field datePickerField : datePickerfFields) {
                    if ("mYearSpinner".equals(datePickerField.getName()) || ("mYearPicker").equals(datePickerField.getName())) {
                        datePickerField.setAccessible(true);
                        Object dayPicker = new Object();
                        try {
                            dayPicker = datePickerField.get(mDatePicker);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        }
                        ((View) dayPicker).setVisibility(View.GONE);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //TimePicker隐藏冒号间隔
    public static void hideTime(TimePicker mTimepicker) {
        ViewGroup view = (ViewGroup) mTimepicker.getChildAt(0);
        ViewGroup view2 = (ViewGroup) view.getChildAt(1);
        view2.getChildAt(1).setVisibility(View.GONE);
    }

    //时间戳转日期
    public static String timeStamp2Date(long time, String format) {
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(time));
    }

}